import hashlib
import time
from datetime import datetime

class Block:
    """
        区块结构
            prev_hash: 父区块的哈希值
            data: 区块内容
            timestamp: 区块创建时间
            hash: 区块哈希值
    """
    def __init__(self, data, prev_hash):
        self.prev_hash = prev_hash
        self.data = data
        self.timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

        # 计算区块的哈希值
        message = hashlib.sha256()
        message.update(str(self.prev_hash).encode("utf-8"))
        message.update(str(self.data).encode("utf-8"))
        message.update(str(self.timestamp).encode("utf-8"))
        self.hash = message.hexdigest()
        self.nonce = None

class BlockChain:
    """
        区块链结构体
        blocks: 包含的区块列表
    """
    def __init__(self):
        self.blocks = []

    def add_block(self,block):
        """
            添加区块
        """
        self.blocks.append(block)
# ------------------------------测试1--------------------------------
# # 生成创世区块
# # 创世区块是第一个区块，无父区块哈希
# genesis_block = Block(data="创世区块", prev_hash="")
# # 再新建两个区块， prev_hash分别为父区块哈希值
# new_block = Block(data="张三转给李四1个比特币", prev_hash=genesis_block.hash)
# new_block2 = Block(data="张三转给王五2个比特币", prev_hash=new_block.hash)
# # 新建一个区块链
# blockChain = BlockChain()
# blockChain.add_block(genesis_block)
# blockChain.add_block(new_block)
# blockChain.add_block(new_block2)
# # 打印区块链
# print("区块链包含的区块个数： %d\n" % len(blockChain.blocks))
# for block in blockChain.blocks:
#     print("父区块哈希： %s" % block.prev_hash)
#     print("区块内容： %s" % block.data)
#     print("区块哈希： %s" %block.hash)
#     print("\n")
# ------------------------------测试1--------------------------------
class ProofOfWork:
    """
        工作量证明
    """
    def __init__(self, block,difficult=5):
        self.block = block
        # 定义工作量难度， 默认为5 ，标识有效的哈希值以5个0开头
        self.difficult = difficult

    def mine(self):
        """
            挖矿函数
        """
        i = 0
        # 00000 前缀
        prefix = '0' * self.difficult
        while True:
            message = hashlib.sha256()
            message.update(str(self.block.prev_hash).encode("utf-8"))
            message.update(str(self.block.data).encode("utf-8"))
            message.update(str(self.block.timestamp).encode("utf-8"))
            # 随机数 暴力 i
            message.update(str(i).encode("utf-8"))
            digest = message.hexdigest()
            if digest.startswith(prefix):
                self.block.nonce = i
                self.block.hash = digest
                return self.block
            i+=1

    def validate(self):
        """
            验证有效性
        """
        message = hashlib.sha256()
        message.update(str(self.block.prev_hash).encode("utf-8"))
        message.update(str(self.block.data).encode("utf-8"))
        message.update(str(self.block.timestamp).encode("utf-8"))
        message.update(str(self.block.nonce).encode("utf-8"))
        digest = message.hexdigest()
        prefix = '0' * self.difficult
        return digest.startswith(prefix)
# ------------------------------测试2------------------------------
# 定义一个区块
# b = Block(data = "测试",prev_hash = "")
# # 再定义一个工作量证明
# w = ProofOfWork(b)
# wStartTime = time.time()
# # 进行挖矿，并统计函数执行时间
# valid_block = w.mine()
# wEndTime = time.time()
# print("挖矿时间s：")
# print(wEndTime - wStartTime)
# # 验证区块，并计算执行时间
# result = w.validate()
# vEndTime = time.time()
# print(vEndTime-wEndTime)
# print(result)
# ------------------------------测试2------------------------------







